#include "logger.h"
#include <QDateTime>
#include <QDir>
#include <QFile>

namespace yc {

Logger::Logger(const QString& file_name, int cache_size) : cache_size_(cache_size)
{
    file_ = new QFile(file_name);
    file_->open(QIODevice::WriteOnly | QIODevice::Truncate);
}

Logger::~Logger()
{
    if (cached_text_.length() > 0) {
        file_->write(cached_text_.toUtf8());
        file_->flush();
    }
    file_->close();
    delete file_;
}

Logger& Logger::operator<<(const QString& text)
{
    mutex_.lock();
    cached_text_ += text;
    if (cached_text_.length() >= cache_size_) {
        file_->write(cached_text_.toUtf8());
        file_->flush();
        cached_text_.clear();
    }
    mutex_.unlock();
    return *this;
}

QString Logger::getLogFileName(const QString& base_name)
{
    const QDateTime now = QDateTime::currentDateTime();
    const QString s1 = now.toString("yyyy_MM_dd");
    const QString s2 = now.toString("hh_mm_ss");
    return QString("%1_%2_%3.log").arg(base_name, s1, s2);
}

void Logger::clearExpiredLogFiles(const QString& dir_path, int days)
{
    QDir log_dir(dir_path);
    if (log_dir.exists()) {
        // current time
        const QDateTime now = QDateTime::currentDateTime();
        // delete log files of 5 days ago
        const QDateTime expire_date = now.addDays(-days);
        const QFileInfoList fl = log_dir.entryInfoList(
                QStringList { QString("*.log") }, QDir::Filters(QDir::Files | QDir::NoSymLinks));
        for (const QFileInfo& fi : fl) {
            if (fi.lastRead() < expire_date) {
                QFile::remove(fi.filePath());
            }
        }
    }
}

namespace {
static QMutex* logMutex()
{
    static QMutex mutex;
    return &mutex;
}
}

LogHandler kLogHandler;

void installLogHandler(LogHandler handler)
{
    kLogHandler = handler;
}

LogStream logStream(int level)
{
    return LogStream(logMutex(), level, kLogHandler);
}

} // namespace yc
